-- UIDailyTask
-- Created by chendh Aug/11/2015
-- 日常任务主界面

require "game/ui/form/daily_task/UIDailyTaskInfo"

UIDailyTask = class("UIDailyTask", function()
    return cc.Layer:create();
end);

local MAX_GRID_COLUMN = 1;
local MAX_GRID_ROW    = DailyTaskM.getDailyTaskNum();

function UIDailyTask.create()
    return UIDailyTask.new();
end

-- 构造函数
function UIDailyTask:ctor()
    self:setName("UIDailyTask");

    -- 初始化
    local node = cc.CSLoader:createNode("layout/dailytask/DailyTask.csb");
    self:addChild(node);
    self.node = node;

    local scrollview = findChildByName(self.node, "CT/scroll_view");
    self.scrollView = scrollview;

    -- 适配
    -- 注：这里适配必须在redraw之前，因为redraw中会重新设置scrollview的尺寸
    self:resize();

    self:initData();

    self:initGrid();

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 重绘
    self:redraw(true);
end

-- 适配
function UIDailyTask:resize()
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    local node = self.node;

    -- bg/mask居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");
    AlignM.fitToScreen(node, "bg2");

    -- TOP顶部居中并缩放至合适大小
    AlignM.alignToTopCenter(node, "TOP");

    -- CT中间居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 注册点击事件
function UIDailyTask:registerTouchEvent()
    local BT = findChildByName(self.node, "BT");

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(BT, "btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");

            UIMgr.getCurrentScene():removeFormByName("UIDailyTask");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);

    -- 注册刷新按钮点事件
    local btnRefresh = findChildByName(BT, "btn_refresh");
    local function onRefreshClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");
            local cost = FormulaM.invoke("CALC_DAILY_TASK_REFRESH_COST");
            local title = getLocStr("refresh_tasks");
            local msg = string.format(getLocStr("daily_task_refresh_confirm"), cost[3], FieldsM.getFieldName(cost[2]), DailyTaskM.getRefreshTimes());
            
            local limitCount = ServerStatusM.query("dalily_task_refresh_limit") or 0;
            local refreshTimes = DailyTaskM.getRefreshTimes();
            if limitCount > 0 and limitCount - refreshTimes <= 10 then
                msg = string.format(getLocStr("daily_task_refresh_confirm_limit"),
                    cost[3],
                    FieldsM.getFieldName(cost[2]),
                    refreshTimes,
                    limitCount - refreshTimes
                );
            end

            local function callback()
                if ME.user.dbase:query(cost[2], 0) < cost[3] then
                    showGemLackConfirm();
                else
                    -- 刷新
                    DailyTaskM.refreshTasks();
                end
            end

            -- 弹出消耗确认提示框
            confirm2(CONFIRM_TYPE_OK, title, msg, callback,
                nil, getLocStr("btn_text_refresh"));
        end
    end
    btnRefresh:addTouchEventListener(onRefreshClick);

    -- 额外奖励按钮点击事件
    local bonusNode = findChildByName(self.node, "CT/extra_bonus");
    local bonusIcon = findChildByName(self.node, "CT/extra_bonus/bonus_icon");
    local function onExtraBonusClick(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            -- 1.变小
            local downTime  = 0.25/2;
            local scaleDown = cc.ScaleTo:create(downTime, 0.8);
            bonusIcon:runAction(scaleDown);
        elseif eventType == ccui.TouchEventType.ended then
            -- 2.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            bonusIcon:runAction(scaleUp);
        elseif eventType == ccui.TouchEventType.canceled then
            -- 3.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            bonusIcon:runAction(scaleUp);
        end

        if eventType == ccui.TouchEventType.ended then
            local bonusList = FormulaM.invoke("CALC_DAILY_TASK_EXTRA_BONUS");
            local finishNum = 0;

            for _, taskInfo in ipairs(self.taskList) do
                if taskInfo.is_finish == 1 then
                    finishNum = finishNum + 1;
                end
            end

            local msg = string.format(getLocStr("daily_task_extra_bonus_desc"), finishNum, DailyTaskM.getDailyTaskNum());
            local title = getLocStr("daily_task_extra_bonus_title");

            local function callback()
                local maxLife = ME.user:getMaxLife();
                local life    = ME.user.dbase:query("life", 0);

                -- 有活力奖励且活力达到上限时
                if DailyTaskM.canGetExtraBonus() and life >= maxLife then
                    alert(getLocStr("cannot_take_life_bonus"));
                    return;
                end

                -- 领取额外奖励
                local ret = DailyTaskM.getExtraBonus();
                if type(ret) == "table" then
                    bonusNode.gainItemList = {};

                    for _, bonus in pairs(ret) do
                        if bonus[1] == 1 then
                            local name = ItemM.query(bonus[2], "name");
                            table.insert(bonusNode.gainItemList, string.format(getLocStr("daily_task_bonus"), name, bonus[3]));
                        elseif bonus[1] == 2 then
                            local name = FieldsM.query(bonus[2], "name");
                            table.insert(bonusNode.gainItemList, string.format(getLocStr("daily_task_bonus"), name, bonus[3]));
                        end
                    end

                    showItemName(bonusNode, TextStyleM.TEXT_COLOR_BRIGHT_YELLOW, nil, bonusNode:getContentSize().height + 6);
                end
            end

            -- 显示获得奖励框
            showBonusNotifyForm(title, bonusList, callback, msg, getLocStr("take_bonus"), DailyTaskM.canGetExtraBonus(), true);
        end
    end

    bonusIcon:addTouchEventListener(onExtraBonusClick);

    -- 累积奖励按钮点击事件
    local bonusNode = findChildByName(self.node, "CT/cumulation_bonus");
    local bonusIcon = findChildByName(self.node, "CT/cumulation_bonus/bonus_icon");
    local function onCumulationBonusClick(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            -- 1.变小
            local downTime  = 0.25/2;
            local scaleDown = cc.ScaleTo:create(downTime, 0.8);
            bonusIcon:runAction(scaleDown);
        elseif eventType == ccui.TouchEventType.ended then
            -- 2.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            bonusIcon:runAction(scaleUp);
        elseif eventType == ccui.TouchEventType.canceled then
            -- 3.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            bonusIcon:runAction(scaleUp);
        end

        if eventType == ccui.TouchEventType.ended then
            local bonusList = FormulaM.invoke("CALC_DAILY_TASK_CUMULATION_BONUS");
            local dailyTaskInfo = ME.user.dbase:query("daily_task_info") or {};
            local finishNum = dailyTaskInfo.cumulation_task_num or 0;

            local msg = string.format(getLocStr("daily_task_cumulation_bonus_desc"), finishNum, DailyTaskM.getCumulationTaskNum());
            local title = getLocStr("daily_task_cumulation_bonus_title");

            local function callback()
                -- 领取累计奖励
                local ret = DailyTaskM.getCumulationBonus();
                if type(ret) == "table" then
                    bonusNode.gainItemList = {};

                    for _, bonus in pairs(ret) do
                        if bonus[1] == 1 then
                            local name = ItemM.query(bonus[2], "name");
                            table.insert(bonusNode.gainItemList, string.format(getLocStr("daily_task_bonus"), name, bonus[3]));
                        elseif bonus[1] == 2 then
                            local name = FieldsM.query(bonus[2], "name");
                            table.insert(bonusNode.gainItemList, string.format(getLocStr("daily_task_bonus"), name, bonus[3]));
                        end
                    end

                    showItemName(bonusNode, TextStyleM.TEXT_COLOR_BRIGHT_YELLOW, nil, bonusNode:getContentSize().height + 6);
                end
            end

            -- 显示获得奖励框
            showBonusNotifyForm(title, bonusList, callback, msg, getLocStr("take_bonus"), DailyTaskM.canGetCumulationBonus(), true);
        end
    end

    bonusIcon:addTouchEventListener(onCumulationBonusClick);
end

-- 注册事件处理回调函数
function UIDailyTask:registerEventCallback()
    -- 注册日常任务信息变化的事件回调
    EventMgr.register("UIDailyTask", event.USER_INFO_UPDATED, function(args)
        if args == "daily_task_info" then
            self:initData();
            self:redraw();
        end
    end);

    -- 注册获得焦点的回调
    EventMgr.register("UIDailyTask", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UIDailyTask" then
            UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_MONEY, TOPMENU_FRAME_GEM);
        end
    end);

    -- 日常任务完成事件
    EventMgr.register("UIDailyTask", event.DAILY_TASK_FINISH, function(args)
        self:initData();
        self:redraw();
    end);

    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            cclog("UIDailyTask 界面析构清理");
            EventMgr.removeAll("UIDailyTask");
        elseif eventType == "enter" then
            -- 播放界面音效
            AudioM.playFx("market_open");

            -- 检查一下daily_task的version
            DailyTaskM.checkTaskVersion();
        end
    end);
end

-- 初始化数据
function UIDailyTask:initData()
    self.taskList = DailyTaskM.getTaskList();
end

-- 初始化列表
function UIDailyTask:initGrid()
    -- 收集日常任务信息信息
    local list = self.taskList;

    -- 日常任务的总个数
    local count = #list;

    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();

    local itemNode = cc.CSLoader:createNode("layout/dailytask/DailyTaskItem.csb");
    local widget = replaceNodeWithWidget(itemNode);
    -- 图标宽度
    local iconWidth = 570;
    -- 图片高度
    local iconHeight = 120;
    -- 图标间距(纵向)
    local hGap = 10;
    local scrollNode = self.scrollView;
    -- 先获取下显示区域的宽度和高度
    local areaWidth = scrollNode:getContentSize().width;
    local areaHeight = scrollNode:getContentSize().height;
    -- 计算单元格分布情况
    local gridList = sortGridsEx(count, MAX_GRID_ROW, MAX_GRID_COLUMN);

    -- 行数
    local rowNum = #gridList;
    local colNum = 0;
    for i = 1, rowNum do
        for j = 1, #gridList[i] do
            local child = widget:clone();
            child:setName("item" .. gridList[i][j]);
            child.index = gridList[i][j];

            -- 计算单元格坐标
            -- 这个坐标将是单元格的描点所在
            local x = 15 + iconWidth / 2;
            local y = areaHeight - (gridList[i][j] - 1) * (iconHeight + hGap) - 20;

            child:setPositionX(x);
            child:setPositionY(y);

            self:registerTaskTouchEvent(child);
            scrollNode:addChild(child)
            table.insert(scrollNode.rows, child)
        end
    end
end

-- 重绘
function UIDailyTask:redraw(showEffect)
    local node = self.node;

    -- 设置标题文本
    local titleLabel = findChildByName(node,"CT/title_node/title")
    titleLabel:setString(getLocStr("daily_task_title"));
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- 绘制重置时间
    local function tick()
        local resetTimeLabel = findChildByName(node, "CT/reset_time");
        local serverTime = TimeM.getServerTime() - TimeM.getTimeOffsetDifference();
        local tableTime = os.date("*t",serverTime);
        local dSecond = tableTime.hour * 3600 + tableTime.min * 60 + tableTime.sec;
        local remainingTime = 86400 - dSecond;

        TextStyleM.setTextStyle(resetTimeLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_LIGHT_YELLOW, true, -3, nil, nil, nil, nil, true);
        resetTimeLabel:setString(string.format(getLocStr("ranking_list_reset_time"), remainingTimeDesc(remainingTime)));

        performWithDelay(self, tick, 1);
    end

    tick();

    -- 设置返回按钮的文本样式
    local btnBack = findChildByName(node, "BT/btn_back");
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 设置刷新按钮的文本样式
    local btnRefresh = findChildByName(node, "BT/btn_refresh");
    TextStyleM.setTextStyle(btnRefresh, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnRefresh:setTitleText(getLocStr("btn_text_refresh"));

    -- 可以刷新的时候刷新按钮才变亮、可点击
    if DailyTaskM.canRefresh() then
        btnRefresh:setBright(true);
        btnRefresh:setTouchEnabled(true);
    else
        btnRefresh:setBright(false);
        btnRefresh:setTouchEnabled(false);
    end

    -- 绘制任务列表
    self:redrawTaskList();

    -- 绘制额外奖励
    self:redrawExtraBonus();

    -- 绘制累积奖励
    self:redrawCumulationBonus();

    -- 需要播放效果
    if showEffect then
        -- 播放界面元素飞入效果
        local list = {};
        for j = 1, #self.scrollView.rows do
            table.insert(list, self.scrollView.rows[j]);
        end

        local extraBonusNode = findChildByName(self.node, "CT/extra_bonus");
        local cumulationBonusNode = findChildByName(self.node, "CT/cumulation_bonus");
        table.insert(list, extraBonusNode);
        table.insert(list, cumulationBonusNode);
        commonScrollItemFlyIn(list);
    end
end

-- 绘制任务列表
function UIDailyTask:redrawTaskList()
    -- 绘制日常任务信息
    local itemCount = #self.taskList;
    local index = 0;

    if not self.taskList or itemCount == 0 then
        cclog("收集日常任务信息失败。");
        return;
    end

    for index = 1, itemCount do
        -- 获取日常任务元素格
        local child = self.scrollView:getChildByName("item" .. index);
        if child == nil then
            break;
        end

        local taskInfo      = self.taskList[index];
        local bgImg         = child:getChildByName("item_bg");
        local bgMask        = child:getChildByName("bg_mask");
        local bgIcon        = child:getChildByName("bg_icon");
        local nameLabel     = child:getChildByName("task_name");
        local requireLabel  = child:getChildByName("task_require");
        local bonusImg      = child:getChildByName("bonus");
        local tipImg        = child:getChildByName("tip");
        local receivedLabel = child:getChildByName("received");

        -- 任务名称
        TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_ORANGE, true, -3, 1.2, nil, nil, nil, true);
        nameLabel:setString(DailyTaskM.query(taskInfo.id, "name"));
        TextStyleM.setOutlineStyle(nameLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

        -- 任务要求
        local requireDesc = DungeonAreaM.query(taskInfo.dungeon_id, "name");
        requireDesc = requireDesc .. " " .. tostring(taskInfo.floor) .. "F";
        TextStyleM.setTextStyle(requireLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, -2, 1.2, nil, nil, nil, true);
        requireLabel:setString(requireDesc);
        TextStyleM.setOutlineStyle(requireLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

        -- "已完成"的图标只有在已完全且未领奖的时候显示
        if taskInfo.is_finish == 1 and taskInfo.received == 0 then
            tipImg:loadTexture(getCornerImg("finish"));
            tipImg:setVisible(true);
            playBubbleAnima(tipImg, false, 1);

            -- 图标显示奖励图标
            local bonusId = taskInfo.bonus_id;
            local icon = DailyTaskM.queryBonus(bonusId, "icon");
            bonusImg:loadTexture(getItemIconPath(icon));
        else
            tipImg:setVisible(false);
            -- 图标显示任务图标
            bonusImg:loadTexture(DailyTaskM.query(taskInfo.id, "icon"));
        end

        bonusImg:stopAllActions();

        if taskInfo.received == 1 then
            -- 底图变成灰白色
            setGrayMode(bgImg, true);
            setGrayMode(bgMask, true);
            setGrayMode(bgIcon, true);

            -- 奖励图标隐藏
            bonusImg:setVisible(false);

            TextStyleM.setTextStyle(receivedLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, -2, 1.2, nil, nil, nil, true);
            receivedLabel:setString(getLocStr("has_received"));
            receivedLabel:setVisible(true);
            TextStyleM.setOutlineStyle(receivedLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);
        else
            -- 底图退出灰白色
            setGrayMode(bgImg, false);
            setGrayMode(bgMask, false);
            setGrayMode(bgIcon, false);

            bonusImg:setVisible(true);

            if taskInfo.is_finish == 1 then
                playBubbleAnima2(bonusImg, false, 0.8);
            end

            receivedLabel:setVisible(false);
        end
    end
end

-- 绘制额外奖励
function UIDailyTask:redrawExtraBonus()
    local finishNum = 0;

    for _, taskInfo in ipairs(self.taskList) do
        if taskInfo.is_finish == 1 then
            finishNum = finishNum + 1;
        end
    end

    local bonusIcon = findChildByName(self.node, "CT/extra_bonus/bonus_icon");
    local bonusLabel = findChildByName(self.node, "CT/extra_bonus/desc");

    bonusIcon:stopAllActions();
    TextStyleM.setTextStyle(bonusLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BEIGE, true, -2, nil, nil, nil, nil, true);
    bonusLabel:setString(string.format(getLocStr("daily_task_extra_bonus"), finishNum, DailyTaskM.getDailyTaskNum()));

    local dailyTaskInfo = ME.user.dbase:query("daily_task_info") or {};

    if dailyTaskInfo.extra_bonus == 1 then
        TextStyleM.setTextStyle(bonusLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, -2, 1.2, nil, nil, nil, true);
        bonusLabel:setString(getLocStr("has_received"));
        TextStyleM.setOutlineStyle(bonusLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

        -- 底图进入灰白色
        setGrayMode(bonusIcon, true);
        bonusIcon:setTouchEnabled(false);
    else
        -- 底图退出灰白色
        setGrayMode(bonusIcon, false);
        bonusIcon:setTouchEnabled(true);
    end

    if DailyTaskM.canGetExtraBonus() then
        bonusIcon:stopAllActions();
        local scaleUp = cc.ScaleTo:create(0.4, 1.05);
        local scaleDown = cc.ScaleTo:create(0.4, 1);

        bonusIcon:runAction(cc.RepeatForever:create(cc.Sequence:create(scaleUp, scaleDown)));
    end
end

-- 绘制累积奖励
function UIDailyTask:redrawCumulationBonus()
    local dailyTaskInfo = ME.user.dbase:query("daily_task_info") or {};
    local finishNum = dailyTaskInfo.cumulation_task_num or 0;

    local bonusIcon = findChildByName(self.node, "CT/cumulation_bonus/bonus_icon");
    local bonusLabel = findChildByName(self.node, "CT/cumulation_bonus/desc");

    bonusIcon:stopAllActions();
    TextStyleM.setTextStyle(bonusLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BEIGE, true, -2, nil, nil, nil, nil, true);
    bonusLabel:setString(string.format(getLocStr("daily_task_extra_bonus"), finishNum, DailyTaskM.getCumulationTaskNum()));

    if DailyTaskM.canGetCumulationBonus() then
        bonusIcon:stopAllActions();
        local scaleUp = cc.ScaleTo:create(0.4, 1.05);
        local scaleDown = cc.ScaleTo:create(0.4, 1);

        bonusIcon:runAction(cc.RepeatForever:create(cc.Sequence:create(scaleUp, scaleDown)));
    end
end

-- 底部BT按钮显示
function UIDailyTask:showButtons()
    local btNode = findChildByName(self.node, "BT");
    btNode:setVisible(true);
end

-- 底部BT按钮隐藏
function UIDailyTask:hideButtons()
    local btNode = findChildByName(self.node, "BT");
    btNode:setVisible(false);
end

-- 隐藏Top
function UIDailyTask:hideMarket()
    local topNode = findChildByName(self.node, "TOP");
    topNode:setVisible(false);

    local btNode = findChildByName(self.node, "BT");
    btNode:setVisible(false);
end

-- 显示Top
function UIDailyTask:showMarket()
    local topNode = findChildByName(self.node, "TOP");
    topNode:setVisible(true);

    local btNode = findChildByName(self.node, "BT");
    btNode:setVisible(true);
end

-- 日常任务点击回调
function UIDailyTask:registerTaskTouchEvent(node)
    local image = node:getChildByName("item_bg");
    local function onClick(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            -- 1.变小
            local downTime  = 0.25/2;
            local scaleDown = cc.ScaleTo:create(downTime, 0.9);
            node:runAction(scaleDown);
        elseif eventType == ccui.TouchEventType.ended then
            -- 2.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            node:runAction(scaleUp);
        elseif eventType == ccui.TouchEventType.canceled then
            -- 3.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            node:runAction(scaleUp);
        end

        -- 点击时的回调
        if eventType == ccui.TouchEventType.ended then
            local index = node.index;
            local taskList = self.taskList;
            local taskInfo = taskList[index];

            if type(taskInfo) == "table" then
                if taskInfo.received == 1 then
                    -- 已经领过奖了，不处理
                elseif taskInfo.is_finish == 1 then
                    AudioM.playFx("button_click");
                    -- 去领奖
                    DailyTaskM.getTaskBonus(index);
                else
                    -- 打开任务信息界面
                    AudioM.playFx("button_click");

                    local uiForm = UIDailyTaskInfo.create(index);
                    UIMgr:getCurrentScene():addForm(uiForm);
                end
            end
        end
    end

    image:addTouchEventListener(onClick);
end